﻿#include "EditEntry.h"
#include "EditEntryUi.h"
#include "PropertyEditView.h"
#include <QPointer>
#include <QMouseEvent>
#include <QPainter>

#include <QApplication>
#include <QStyle>

#include <QDebug>
#define DEBUG qDebug().noquote()

#include <QTimer>
extern QPointer<QTimer> propertyInspectorTimer();

struct EditEntry::GroupBoxPrivate {
    QPointer<PropertyEditView> editView;
    QPointer<EditEntry> parentBox;
    QList<QPointer<EditEntry>> childBoxList;
    QColor editPanelBackground;
    bool expanded { false };
};

EditEntry::~EditEntry() { }

EditEntry::EditEntry(QWidget *parent) : QWidget{parent} {
    p.reset(new GroupBoxPrivate);
    ui.reset(new EditEntryUi);
    ui->SetupUI(this);

    editPanel()->setFixedHeight(20);
    connect(propertyInspectorTimer().data(), &QTimer::timeout, this, &EditEntry::updateIndent);
}

void EditEntry::setTitle(const QString &title) {
    ui->labelName->setText(title);
}

QString EditEntry::title() const {
    return ui->labelName->text();
}

void EditEntry::addEditControll(QWidget *controll, int stretch) {
    CreateEditArea();
    ui->layoutEditArea->addWidget(controll, stretch);
}

void EditEntry::AddOperateControll(QWidget *controll) {
    CreateOperateArea();
    ui->layoutOperateArea->addWidget(controll);
}

void EditEntry::appendChildEntry(EditEntry *box) {
    box->setParentBox(this);
    p->childBoxList.append(box);
    CreateChildPanel();
    ui->layoutPanelChild->addWidget(box);
}

void EditEntry::setEditPanelBackground(const QColor &color) {
    if (p->editPanelBackground == color) {
        return;
    }
    p->editPanelBackground = color;
    update();
}

QList<QPointer<EditEntry>> EditEntry::childEntries() const {
    return p->childBoxList;
}

EditEntry* EditEntry::parentBox() const {
    return p->parentBox;
}

void EditEntry::setNameAreaWidth(int width) {
    if(!ui->areaEdit) return;
    ui->areaName->setFixedWidth(width);
}

void EditEntry::setEditView(PropertyEditView *view) {
    p->editView = view;
}

QWidget* EditEntry::editPanel() const {
    return ui->panelEdit; 
}

QWidget* EditEntry::childPanel() const {
    return ui->panelChild; 
}

void EditEntry::setParentBox(EditEntry* box) {
    p->parentBox = box;
    updateIndent();
}

void EditEntry::expandOrCollapse() {
    if(ui->panelChild) {
        if (p->expanded) {
            collapse();
        } else {
            expand();
        }       
    }
}

void EditEntry::expand() {
    if(!ui->panelChild || p->expanded) {
        return ;
    }

    p->expanded = true;
    ui->panelChild->show();
    emit expandedOrCollapsed();
    updateExpandButtons();
}

void EditEntry::collapse() {
    if (!ui->panelChild || !p->expanded) {
        return;
    }

    p->expanded = false;
    ui->panelChild->hide();
    emit expandedOrCollapsed();
    updateExpandButtons();
}

void EditEntry::updateIndent() {
    int level = 0;
    auto parent = parentBox();
    while (parent) {
        ++level;
        parent = parent->parentBox();
    }

    auto margins = ui->layoutNameArea->contentsMargins();
    margins.setLeft(level *20);
    ui->layoutNameArea->setContentsMargins(margins);

    if (Q_LIKELY(ui->areaEdit) && Q_LIKELY(p->editView)) {
        ui->areaName->setFixedWidth(p->editView->headerSizes().first());
    }
}

void EditEntry::updateSectionWidth(int width) {
    if(Q_UNLIKELY(!ui->areaEdit)) {
        return ;
    }

    ui->areaName->setFixedWidth(width);
}

void EditEntry::updateExpandButtons() {
    ui->buttonExpend->setVisible(!p->expanded);
    ui->buttonCollapse->setVisible(p->expanded);
}

void EditEntry::mouseDoubleClickEvent(QMouseEvent *event) {
    QWidget::mouseDoubleClickEvent(event);
    const auto &localPoint = ui->panelEdit->mapFrom(this, event->pos());
    if(ui->panelEdit->rect().contains(localPoint)) {
        expandOrCollapse();
    }
}

void EditEntry::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    auto rct = ui->panelEdit->geometry();
    rct.moveTopLeft(ui->panelEdit->mapTo(this, QPoint(0, 0)));
    painter.fillRect(rct, p->editPanelBackground);
}

void EditEntry::CreateEditArea() {
    if(Q_LIKELY(ui->areaEdit)) {
        return ;
    }

    ui->layoutEditArea = new QHBoxLayout;
    ui->layoutEditArea->setContentsMargins(3,1,3,1);
    ui->layoutEditArea->setSpacing(3);

    ui->areaEdit = new QWidget;
    ui->areaEdit->setObjectName("EntryEditArea");
    ui->areaEdit->setStyleSheet(R"(
        QWidget#EntryEditArea {
            border-left: 1px solid #C8C8C8;
        }
    )");
    ui->areaEdit->setLayout(ui->layoutEditArea);

    ui->layoutEditPanel->insertWidget(1, ui->areaEdit, 1);
}

void EditEntry::CreateOperateArea() {
    if(Q_LIKELY(ui->areaOperate)) {
        return ;
    }

    ui->layoutOperateArea = new QHBoxLayout;
    ui->layoutOperateArea->setDirection(QBoxLayout::Direction::RightToLeft);
    ui->layoutOperateArea->setContentsMargins(0,0,0,0);
    ui->layoutOperateArea->setSpacing(3);

    ui->areaOperate = new QWidget;
    ui->areaOperate->setObjectName("EntryOperateArea");
    ui->areaOperate->setLayout(ui->layoutOperateArea);

    ui->layoutEditPanel->addWidget(ui->areaOperate, 0, Qt::AlignVCenter | Qt::AlignRight);
}

void EditEntry::CreateChildPanel() {
    if(Q_LIKELY(ui->panelChild)) {
        return ;
    }

    ui->layoutPanelChild = new QVBoxLayout;
    ui->layoutPanelChild->setContentsMargins(0,1,0,0);
    ui->layoutPanelChild->setSpacing(1);

    ui->panelChild = new QWidget;
    ui->panelChild->setObjectName("EntryChildPanel");
    ui->panelChild->setLayout(ui->layoutPanelChild);
    ui->panelChild->setStyleSheet(R"(
        QWidget#EntryChildPanel {
            background-color: #A0A0A0;
        }
    )");

    ui->layoutRoot->addWidget(ui->panelChild);
    ui->panelChild->setVisible(p->expanded);
    CreateExpandButtons();
}

void EditEntry::CreateExpandButtons() {
    if(p->childBoxList.isEmpty()) {
        return ;
    }

    ui->buttonExpend = new QPushButton;
    ui->buttonExpend->setFlat(true);
    ui->buttonExpend->setFixedSize(20, 20);
    ui->buttonExpend->setIconSize(QSize(16, 16));
    ui->buttonExpend->setIcon(QIcon(":/Icons/listNormal.png"));
    connect(ui->buttonExpend, &QPushButton::clicked, this, &EditEntry::expand);

    ui->buttonCollapse = new QPushButton;
    ui->buttonCollapse->setFlat(true);
    ui->buttonCollapse->setFixedSize(20, 20);
    ui->buttonCollapse->setIconSize(QSize(16, 16));
    ui->buttonCollapse->setIcon(QIcon(":/Icons/listExpand.png"));
    connect(ui->buttonCollapse, &QPushButton::clicked, this, &EditEntry::collapse);

    ui->layoutNameArea->insertWidget(0, ui->buttonExpend);
    ui->layoutNameArea->insertWidget(0, ui->buttonCollapse);

    updateExpandButtons();
}
